package home.projects.recipes.chapone;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Map.Entry;
import java.util.regex.Pattern;

import org.apache.commons.beanutils.PropertyUtils;

/**
 * The core concept in implementing an IOC; the container is reponsbile for
 * centralizing object creation and managing the life cycle of any object. It
 * also provides for lookup services i.e. looking up objects based on
 * identifiers.
 * 
 * @author SANJAY
 * 
 */
public class Container {

   private Map<String, Object> components;

   public Container() {
      components = new HashMap<String, Object>();
      Properties props = new Properties();            
      try {
         props.load(getClass().getResourceAsStream(
            "/home/projects/recipes/config/chapone-config"));
         for (Entry entry : props.entrySet()) {
            String key = (String)entry.getKey();
            String val = (String)entry.getValue();
            processEntry(key, val);
         }
      } catch (Exception e) {
         throw new RuntimeException(e);
      }
   }

   private void processEntry(String key, String val) throws Exception {
      // If a DOT character is present in the key means that we are
      // attempting a setter injection; lookup the already declared
      // object using key as the key.
      if (key.indexOf('.') != -1) {
         String[] arr = key.split(Pattern.quote("."));
         if (arr.length != 2) {
            throw new IllegalArgumentException("Invalid entry: " + key);
         }
         Object target = components.get(arr[0]);
         Object dependency = components.get(val);
         PropertyUtils.setProperty(target, arr[1], dependency);
      } else {
         // It's a component declaration; create a new instance and
         // place it against the key provided.
         Object instance = Class.forName(val).newInstance();
         components.put(key, instance);
      }
   }

   public Object getComponent(String id) {
      return components.get(id);
   }

}
